package com.ruoyi.cs.service.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.enums.ConsumeType;
import com.ruoyi.common.enums.TaskType;
import com.ruoyi.common.enums.ThresholdType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.domain.vo.ConsumeTypeVo;
import com.ruoyi.cs.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.cs.service.ITTaskService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 任务Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-02
 */
@Service
@SuppressWarnings("all")
public class TTaskServiceImpl implements ITTaskService
{
    @Autowired
    private TTaskMapper tTaskMapper;
    @Autowired
    private TTaskReceiveMapper tTaskReceiveMapper;
    @Autowired
    private TRechargeMapper tRechargeMapper;
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private TBalanceChangeMapper tBalanceChangeMapper;
    @Autowired
    private TGoodsPoolMapper tGoodsPoolMapper;
    @Autowired
    private TBackpackMapper tBackpackMapper;

    /**
     * 查询任务
     *
     * @param id 任务主键
     * @return 任务
     */
    @Override
    public TTask selectTTaskById(Long id)
    {
        return tTaskMapper.selectTTaskById(id);
    }

    /**
     * 查询任务列表
     *
     * @param tTask 任务
     * @return 任务
     */
    @Override
    public List<TTask> selectTTaskList(TTask tTask)
    {
        List<TTask> list = tTaskMapper.selectTTaskList(tTask);
        this.completionGoods(list);
        return list;
    }

    public void completionGoods(List<TTask> list){
        if(CollectionUtil.isNotEmpty(list)){
            List<String> goodsIds = list.stream().filter(bean -> bean.getRewardType() == 1).distinct().map(TTask::getGoodsPoolId).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(goodsIds)){
                List<TGoodsPool> tGoodsPools = tGoodsPoolMapper.batchQueryById(goodsIds);
                Map<String, TGoodsPool> map = tGoodsPools.stream().collect(Collectors.toMap(TGoodsPool::getGoodsId,goodsPool -> goodsPool));

                list.forEach(task -> {
                    if( task.getRewardType() == 1 && map.get(task.getGoodsPoolId()) != null){
                        TGoodsPool tGoodsPool = map.get(task.getGoodsPoolId());
                        task.setGoodsName(tGoodsPool.getGoodsName());
                        task.setGoodsPic(tGoodsPool.getGoodsPic());
                        task.setGoodsPrice(tGoodsPool.getGoodsPrice());
                    }
                });
            }
        }
    }

    /**
     * 新增任务
     *
     * @param tTask 任务
     * @return 结果
     */
    @Override
    public Response insertTTask(TTask tTask)
    {
        tTask.setCreateTime(DateUtils.getNowDate());
        tTask.setDelFlag("1");
        if(1 == tTask.getRewardType()){
            if(tTask.getGoodsPoolId() == null){
                return Response.fail("请填写商品ID");
            }else {
                /**判断商品池ID是否存在*/
                TGoodsPool tGoodsPool = tGoodsPoolMapper.selectTGoodsPoolById(tTask.getGoodsPoolId().toString());
                if(tGoodsPool == null){
                    return Response.fail("该商品不存在饰品池中");
                }
            }
        }
        tTaskMapper.insertTTask(tTask);
        return Response.success("新增成功");
    }

    /**
     * 修改任务
     *
     * @param tTask 任务
     * @return 结果
     */
    @Override
    public Response updateTTask(TTask tTask)
    {
        tTask.setUpdateTime(DateUtils.getNowDate());
        if(tTask.getRewardType() != null && 1 == tTask.getRewardType()){
            if(tTask.getGoodsPoolId() == null){
                return Response.fail("请填写商品ID");
            }else {
                /**判断商品池ID是否存在*/
                TGoodsPool tGoodsPool = tGoodsPoolMapper.selectTGoodsPoolById(tTask.getGoodsPoolId().toString());
                if(tGoodsPool == null){
                    return Response.fail("该商品不存在饰品池中");
                }
            }
        }
        tTaskMapper.updateTTask(tTask);
        return Response.success("更新成功");
    }

    /**
     * 批量删除任务
     *
     * @param ids 需要删除的任务主键
     * @return 结果
     */
    @Override
    public Response deleteTTaskByIds(Long[] ids)
    {
        tTaskMapper.deleteTTaskByIds(ids);
        return Response.success();
    }

    /**
     * 删除任务信息
     *
     * @param id 任务主键
     * @return 结果
     */
    @Override
    public int deleteTTaskById(Long id)
    {
        return tTaskMapper.deleteTTaskById(id);
    }

    /**
     * 统计任务完成人数
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public Response countTaskCompleteNum(String startTime, String endTime) {
        Map map = new HashMap();
        Long allCompleteNum = tTaskReceiveMapper.countTaskCompleteNum(null,null);
        map.put("allCompleteNum",allCompleteNum);
        Long rangeCompleteNum = tTaskReceiveMapper.countTaskCompleteNum(startTime,endTime);
        map.put("rangeCompleteNum",rangeCompleteNum);
        return Response.success(map);
    }

    /**
     * 任务列表
     * @param tTask
     * @param userId
     * @return
     */
    @Override
    public List<TTask> taskList(TTask tTask, String userId) {
        List<TTask> tTaskList = tTaskMapper.taskList(tTask);
        if(userId == null){
            /**未登录状态下*/
            return tTaskList;
        }
        if(!CollectionUtils.isEmpty(tTaskList)){
            List<Long> taskIds = tTaskList.stream().map(TTask::getId).collect(Collectors.toList());
            BigDecimal czMoney =null;
            List<ConsumeTypeVo> consumeAmountMap = null;
            List<TTaskReceive> tTaskReceives =  null;
            /**每日任务*/
            if(TaskType.DAILY.getCode().equals(tTask.getType())){
                /**当日充值*/
                czMoney = tRechargeMapper.selectTheDayCzCountByUserId(userId);
                /**当日消费流水*/
                consumeAmountMap = tBalanceChangeMapper.consumeEverydayCount(userId);
                /**当日领取记录*/
                tTaskReceives = tTaskReceiveMapper.batchQueryEverydayReceive(taskIds,userId);
            }else if(TaskType.MONTHLY.getCode().equals(tTask.getType())){ /**每月任务*/
                /**当月充值*/
                czMoney = tRechargeMapper.selectTheMonthCzCountByUserId(userId);
                /**当月消费流水*/
                consumeAmountMap = tBalanceChangeMapper.consumeEveryMonthCount(userId);
                /**当月领取记录*/
                tTaskReceives = tTaskReceiveMapper.batchQueryEveryMonthReceive(taskIds,userId);
            }else {/**新手任务*/
                TUser tUser = tUserMapper.selectTUserById(userId);
                /**累计充值*/
                czMoney = tUser.getVipRecharge();
                /**累计消费*/
                consumeAmountMap = tBalanceChangeMapper.consumeTotalCount(userId);
                /**所有领取记录*/
                tTaskReceives = tTaskReceiveMapper.batchQueryGrowUpReceive(taskIds,userId);
            }
            for (TTask task : tTaskList) {
                task.setCzMoney(czMoney);
                BigDecimal consumeAmount = findMapByKey(consumeAmountMap,task.getConsumeType());
                task.setConsumeAmount(consumeAmount);
                /**判断任务是否已领取*/
                long receivenum = tTaskReceives.stream().filter(bean -> bean.getTaskId().equals(task.getId())).count();
                if(receivenum > 0){
                    task.setUserStatus("0");
                }else {
                    /**表示未领取过，再判断是否满足领取条件*/
                    if(ThresholdType.RECHARGE.getCode() == task.getThresholdType()){
                        /**充值门槛*/
                        if(czMoney.compareTo(task.getThreshold()) >= 0){
                            task.setUserStatus("1");
                        }else {
                            task.setUserStatus("2");
                        }
                    }else {
                        /**消费门槛*/
                        if(consumeAmount.compareTo(task.getThreshold()) >= 0){
                            task.setUserStatus("1");
                        }else {
                            task.setUserStatus("2");
                        }
                    }
                }
            }
        }
        this.completionGoods(tTaskList);
        return tTaskList;
    }

    /**
     * 领取任务奖励
     * @param taskId
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public Response taskReceive(long taskId, String userId) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())) {
            return Response.fail("账号不存在或已被冻结!");
        }
        TTask tTask = tTaskMapper.selectTTaskById(taskId);
        if(tTask == null || !Constants.SUCCESS.equals(tTask.getDelFlag())){
            return Response.fail("任务不存在!");
        }
        /**判断任务类型，确定是否已领取过*/
        if(TaskType.DAILY.getCode().equals(tTask.getType())){/**每日任务*/
            long erverday = tTaskReceiveMapper.everydayReceiveById(taskId,userId);
            if(erverday > 0){
                return Response.fail("任务已领取!");
            }
            if(ThresholdType.RECHARGE.getCode() == tTask.getThresholdType()){
                /**当日充值*/
                BigDecimal todayCzMoney = tRechargeMapper.selectTheDayCzCountByUserId(userId);
                if(todayCzMoney.compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }else {
                /**流水门槛*/
                List<ConsumeTypeVo> consumeAmountMap = tBalanceChangeMapper.consumeEverydayCount(userId);
                BigDecimal consumeAmount = findMapByKey(consumeAmountMap,tTask.getConsumeType());
                if(consumeAmount.compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }
        }else if(TaskType.MONTHLY.getCode().equals(tTask.getType())){/**每月任务*/
            long erverday = tTaskReceiveMapper.everyMonthReceiveById(taskId,userId);
            if(erverday > 0){
                return Response.fail("任务已领取!");
            }
            if(ThresholdType.RECHARGE.getCode() == tTask.getThresholdType()){
                /**每月充值*/
                BigDecimal toMonthCzMoney = tRechargeMapper.selectTheMonthCzCountByUserId(userId);
                if(toMonthCzMoney.compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }else {
                /**流水门槛*/
                List<ConsumeTypeVo> consumeAmountMap = tBalanceChangeMapper.consumeEveryMonthCount(userId);
                BigDecimal consumeAmount = findMapByKey(consumeAmountMap,tTask.getConsumeType());
                if(consumeAmount.compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }
        }else {
            long growUp = tTaskReceiveMapper.growUpReceiveById(taskId,userId);
            if(growUp > 0){
                return Response.fail("任务已领取!");
            }
            if(ThresholdType.RECHARGE.getCode() == tTask.getThresholdType()){
                /**累计充值*/
                if(tUser.getVipRecharge().compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }else {
                /**流水门槛*/
                List<ConsumeTypeVo> consumeAmountMap = tBalanceChangeMapper.consumeTotalCount(userId);
                BigDecimal consumeAmount = findMapByKey(consumeAmountMap,tTask.getConsumeType());
                if(consumeAmount.compareTo(tTask.getThreshold()) < 0){
                    return Response.fail("不符合领取条件，无法领取!");
                }
            }
        }
        BigDecimal userBlance = tUser.getUserBalance();
        BigDecimal profitPrice = BigDecimal.ZERO;
        BigDecimal changeFee = BigDecimal.ZERO;
        /**符合领取条件，进行领取操作*/
        if(0 == tTask.getRewardType()){/**金币*/
            /**领取奖励至用户余额*/
            tUser.setUserBalance(userBlance.add(tTask.getReward()));
            int row = tUserMapper.updateTUserBalance(tUser);
            if(row < 1){
                return Response.fail("领取失败，请刷新重试!");
            }
            profitPrice = profitPrice.add(tTask.getReward());
            changeFee = changeFee.add(tTask.getReward());
        }else if(1 == tTask.getRewardType()){
            /**领取商品*/
            TGoodsPool tGoods = tGoodsPoolMapper.selectTGoodsPoolById(tTask.getGoodsPoolId());
            String bbId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
            TBackpack backpack = new TBackpack();
            backpack.setBbId(bbId);
            backpack.setUserId(userId);
            backpack.setGoodsId(tGoods.getGoodsId());
            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE11);
            backpack.setGoodsBelongingId(tGoods.getGoodsId());
            backpack.setGoodsBelongingName(tGoods.getGoodsName());
            backpack.setGoodsPrice(tGoods.getGoodsPrice());
            backpack.setGoodsExprice(tGoods.getGoodsExprice());
            backpack.setBbStatus(Constants.BBSTATUS0);
            backpack.setDelFlag(Constants.SUCCESS);
            backpack.setCreateTime(DateUtils.getNowDate());
            backpack.setGoodsNum(1);
            backpack.setGoodsType(tGoods.getGoodsType());
            backpack.setUserPromotersId(tUser.getUserPromotersId());
            backpack.setOpenBoxPrice(BigDecimal.ZERO);
            backpack.setAuditStatus(Constants.AUDITSTATUS0);
            backpack.setOpenBeforeBalance(userBlance);
            backpack.setOpenAfterBalance(userBlance);
            backpack.setBbGoodsName(tGoods.getGoodsName());
            backpack.setBbGoodsPic(tGoods.getGoodsPic());
            backpack.setBbGoodsGrate(tGoods.getGoodsGrate());
            tBackpackMapper.insertTBackpack(backpack);

            profitPrice = profitPrice.add(tGoods.getGoodsPrice());
        }else {
            return Response.fail("奖品存在异常，无法领取!");
        }


        TTaskReceive tTaskReceive = new TTaskReceive();
        tTaskReceive.setUserId(userId);
        tTaskReceive.setTaskId(taskId);
        tTaskReceive.setTaskThreshold(tTask.getThreshold());
        tTaskReceive.setTaskReward(tTask.getReward());
        tTaskReceive.setTaskType(tTask.getType());
        tTaskReceive.setCreateTime(DateUtils.getNowDate());
        tTaskReceive.setConsumeType(tTask.getConsumeType());
        tTaskReceive.setThresholdType(tTask.getThresholdType());
        tTaskReceive.setRewardType(tTask.getRewardType());
        tTaskReceive.setGoodsPoolId(tTask.getGoodsPoolId());
        tTaskReceiveMapper.insertTTaskReceive(tTaskReceive);


        TBalanceChange balanceChange = new TBalanceChange();
        balanceChange.setUserId(userId);
        balanceChange.setBalanceBefore(userBlance);
        balanceChange.setBalanceAfter(tUser.getUserBalance());
        if(TaskType.DAILY.getCode().equals(tTask.getType())){
            balanceChange.setOperationType(Constants.OPERATIONTYPE12);
        }else if(TaskType.MONTHLY.getCode().equals(tTask.getType())){
            balanceChange.setOperationType(Constants.OPERATIONTYPE13);
        } else {
            balanceChange.setOperationType(Constants.OPERATIONTYPE16);
        }
        balanceChange.setFrequency(1);
        balanceChange.setFee(changeFee);
        balanceChange.setCorrespondingid(tTaskReceive.getId().toString());
        balanceChange.setCreateTime(DateUtils.getNowDate());
        balanceChange.setSecondCurrencyBefore(tUser.getSecondCurrency());
        balanceChange.setSecondCurrencyAfter(tUser.getSecondCurrency());
        balanceChange.setConsumeValue(BigDecimal.ZERO);
        balanceChange.setProfitPrice(profitPrice);
        balanceChange.setCostFee(BigDecimal.ZERO);
        tBalanceChangeMapper.insertTBalanceChange(balanceChange);

        return Response.success("领取成功");
    }

    public static BigDecimal findMapByKey(List<ConsumeTypeVo> list, Integer keyToFind) {
        if(CollectionUtil.isEmpty(list)){
            return BigDecimal.ZERO;
        }
        String key = "";
        if(ConsumeType.ALL.getCode() == keyToFind){
            BigDecimal result = list.stream().map(ConsumeTypeVo::getFee).reduce(BigDecimal.ZERO, BigDecimal::add);
            return  result;
        }else if(ConsumeType.UNBOXING.getCode() == keyToFind){
            key = Constants.OPERATIONTYPE1;
        }else if(ConsumeType.BATTLE.getCode() == keyToFind){
            key = Constants.OPERATIONTYPE6;
        }else if(ConsumeType.LUCKY_ITEMS.getCode() == keyToFind){
            key = Constants.OPERATIONTYPE2;
        }else if(ConsumeType.MINESWEEPER.getCode() == keyToFind){
            key = Constants.OPERATIONTYPE10;
        }

        // 遍历 List 中的每个 Map
        for (ConsumeTypeVo vo : list) {
            // 检查当前 Map 是否包含指定的键
            if(vo.getType().equals(key)){
                return vo.getFee();
            }
        }
        return BigDecimal.ZERO;
    }
}
